package Chatroom;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

// 服务器向客户端推送系统级消息
class Push implements Runnable {
    // 客户端列表
    private List<RegisteredClient> registeredClient;
    // 服务器级消息
    private String systemMessage;

    public void setSystemMessage(String message) {
        this.systemMessage = message;
    }

    public void setUserList(List<RegisteredClient> clientList) {
        this.registeredClient = clientList;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(1000);
            // 向每个客户端推送新人报道消息
            for (int i = 0; i < registeredClient.size(); i++) {
                Socket socket = registeredClient.get(i).getSocket();
                PrintWriter out = new PrintWriter(socket.getOutputStream());
                out.println(systemMessage);
                out.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

// 客户类（已注册）
class RegisteredClient {
    private String userName;
    private String userFrom;
    private Socket socket;

    public RegisteredClient(String name, String from, Socket socket) {
        this.userName = name;
        this.userFrom = from;
        this.socket = socket;
    }

    public String getUserFrom() {
        return userFrom;
    }

    public String getUserName() {
        return userName;
    }

    public Socket getSocket() {
        return socket;
    }
}

public class ChatServer implements Runnable {
    // 客户端列表
    static List<RegisteredClient> clientList = new ArrayList<RegisteredClient>();

    static Socket currentSocket = null;
    static ServerSocket serverSocket = null;

    public ChatServer() {
        try {
            serverSocket = new ServerSocket(9999);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 由服务器转发各客户端的消息
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
            BufferedReader in = new BufferedReader(new InputStreamReader(currentSocket.getInputStream()));
            while (true) {
                String receivedData = in.readLine();
                if (receivedData != null && !"".equals(receivedData)) {
                    for (int i = 0; i < clientList.size(); i++) {
                        Socket socket = clientList.get(i).getSocket();
                        PrintWriter out = new PrintWriter(socket.getOutputStream());
                        out.println(receivedData);
                        out.flush();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 注册客户端
    public RegisteredClient register(Socket socket) {
        RegisteredClient client = new RegisteredClient("Guest", "China", socket);
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String receivedData = in.readLine();
            if (receivedData != null && receivedData.startsWith("[SYS]")) {
                String info = receivedData.substring(5);
                String[] data = info.split(";");
                client = new RegisteredClient(data[0], data[1], socket);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return client;
    }

    public static void main(String[] args) {
        System.out.println("************ 服务端启动 *************");
        ChatServer server = new ChatServer();
        int count = 0;
        while (true) {
            try {
                currentSocket = serverSocket.accept();
                // 注册客户端
                RegisteredClient client = server.register(currentSocket);
                // 服务器通知有新客户端进入
                Push push = new Push();
                push.setUserList(clientList);
                push.setSystemMessage("来自【"+ client.getUserFrom() + "】的朋友【" + client.getUserName() +"】进入聊天室 ^_^");
                // 日后继续为该客户推送消息
                Thread tPush = new Thread(push);
                tPush.start();
                clientList.add(client);
                count++;
                System.out.println("第" + count + "个客户端已连接，客户端总数：" + clientList.size());

                // 由服务器转发各客户端的消息
                Thread tRelay = new Thread(server);
                tRelay.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
